
void httpExec(clientRequestTask *t)
{
    // 文件在系统中的绝对路径
    sprintf(t->path, "%s%s", t->xp->path, t->uri);

    // 文件是否存在
    int find = 1;
    struct stat st;

    if (stat(t->path, &st) == -1) {
        find = 0;
    } else {
        if ((st.st_mode & S_IFMT) != S_IFREG) {
            find = 0;
        }
    }

    if (!find) {
        httpResponse(t, 404, NULL, NULL, 0);
        return;
    }

    // 引用 executer 的管道 fd
    extern int exfd[2];

    // 加锁
    pthread_mutex_lock(&_execLock);

    // 先输出长度，再输出数据
    int len = strlen(t->path);
    write(exfd[1], &len, sizeof(int));
    write(exfd[1], t->path, len);

    // htpp 的 body 部分
    if (t->contentLength > 0) {
        int total = 0;
        while (total < t->contentLength) {
            len = recv(t->fd, t->line, 1024, 0);
            if (len == 0) {
                break;
            } else if (len == -1) {
                if (errno == EAGAIN && t->exit == 0) {
                    sem_wait(&(t->sem));
                    continue;
                }
                break;
            } else {
                total += len;
                write(exfd[1], &len, sizeof(int));
                write(exfd[1], t->line, len);
            }
        }
    }

    // 最后向管道输出 0 长度，表示结束
    len = 0;
    write(exfd[1], &len, sizeof(int));

    // 解锁
    pthread_mutex_unlock(&_execLock);

    // 回应客户端
    httpResponse(t, 200, NULL, NULL, 0);
}
